package lex.dm.ui.dt;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import javax.swing.border.EmptyBorder;

import org.lex.swing.ActionBuilder;
import org.lex.utils.Pair;

import lex.dm.cluster.ClusterUtils;
import lex.dm.id3.IDataSet;

public class ClusteringDialog extends JDialog
{
	private JPanel pane = null;
	private JLabel nodeLabel;
	private JButton okButton;
	private JPanel buttonsPane;
	private JTable table;
	private JScrollPane scrollPane;
	private JComboBox algorithmComboBox;
	private JLabel algorithmLabel;
	// -------------------------------
	private ClusteringTableModel tableModel = new ClusteringTableModel();
	private Pair<? extends IDataSet, ? extends IDataSet> datas = null;

	public static Pair<? extends IDataSet, ? extends IDataSet> cluster( Window owner,
		IDataSet trainingSet, IDataSet testingSet )
	{
		ClusteringDialog d = new ClusteringDialog( owner );
		d.datas = Pair.wrap( trainingSet, testingSet );
		d.setDataSet( trainingSet );
		d.setModal( true );
		d.setVisible( true );
		return d.datas;
	}

	public ClusteringDialog( Window owner )
	{
		super( owner );
		initialize();
		this.setLocationRelativeTo( owner );
	}

	private void setDataSet( IDataSet dataSet )
	{
		this.tableModel.setDataSet( dataSet );
	}

	private void ok()
	{
		int[] k = tableModel.getK();
		IDataSet f = ClusterUtils.kmeans( k, datas.first() );
		IDataSet s = ClusterUtils.kmeans( k, datas.second() );
		this.datas = Pair.wrap( f, s );
		this.dispose();
	}

	private void initialize()
	{
		this.setContentPane( this.getPane() );
		setTitle( "��ɢ����������" );
		this.setSize( 450, 350 );
		this.setModal( true );
		this.setDefaultCloseOperation( JDialog.DISPOSE_ON_CLOSE );
		// --------------------------------------------------------
		JPopupMenu popup = new JPopupMenu();
		popup.add( new ActionBuilder( "Set All to..." ).setActionListener( new ActionListener(){
			@Override
			public void actionPerformed( ActionEvent e )
			{
				String str = JOptionPane.showInputDialog( ClusteringDialog.this,
					"Enter split number", "2" );
				if( null == str )
					return;
				int k = Integer.parseInt( str );
				for( int i = 0, n = tableModel.getRowCount()-1; i < n; i++ )
					tableModel.setValueAt( k, i, 1 );
				tableModel.fireTableDataChanged();
			}
		} ) );
		this.getTable().setComponentPopupMenu( popup );
	}

	private JPanel getPane()
	{
		if( null == pane )
		{
			pane = new JPanel();
			pane.setBorder( new EmptyBorder( 12, 12, 12, 12 ) );
			final GridBagLayout gridBagLayout = new GridBagLayout();
			gridBagLayout.rowHeights = new int[]{ 0, 7, 7 };
			gridBagLayout.columnWidths = new int[]{ 0, 7 };
			pane.setLayout( gridBagLayout );
			final GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.insets = new Insets( 0, 0, 6, 0 );
			gridBagConstraints.anchor = GridBagConstraints.WEST;
			gridBagConstraints.gridy = 0;
			gridBagConstraints.gridx = 0;
			pane.add( getAlgorithmLabel(), gridBagConstraints );
			final GridBagConstraints gridBagConstraints_1 = new GridBagConstraints();
			gridBagConstraints_1.insets = new Insets( 0, 6, 6, 0 );
			gridBagConstraints_1.anchor = GridBagConstraints.WEST;
			gridBagConstraints_1.gridy = 0;
			gridBagConstraints_1.gridx = 1;
			pane.add( getAlgorithmComboBox(), gridBagConstraints_1 );
			final GridBagConstraints gridBagConstraints_2 = new GridBagConstraints();
			gridBagConstraints_2.insets = new Insets( 0, 0, 1, 0 );
			gridBagConstraints_2.gridwidth = 2;
			gridBagConstraints_2.weighty = 1;
			gridBagConstraints_2.weightx = 1;
			gridBagConstraints_2.fill = GridBagConstraints.BOTH;
			gridBagConstraints_2.gridy = 1;
			gridBagConstraints_2.gridx = 0;
			pane.add( getScrollPane(), gridBagConstraints_2 );
			final GridBagConstraints gridBagConstraints_3 = new GridBagConstraints();
			gridBagConstraints_3.weightx = 1;
			gridBagConstraints_3.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints_3.gridwidth = 2;
			gridBagConstraints_3.gridy = 3;
			gridBagConstraints_3.gridx = 0;
			final GridBagConstraints gridBagConstraints_4 = new GridBagConstraints();
			gridBagConstraints_4.gridwidth = 2;
			gridBagConstraints_4.weightx = 1;
			gridBagConstraints_4.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints_4.insets = new Insets( 0, 0, 12, 0 );
			gridBagConstraints_4.gridy = 2;
			gridBagConstraints_4.gridx = 0;
			pane.add( getNodeLabel(), gridBagConstraints_4 );
			pane.add( getButtonsPane(), gridBagConstraints_3 );
		}
		return pane;
	}

	/**
	 * @return
	 */
	private JLabel getAlgorithmLabel()
	{
		if( algorithmLabel == null )
		{
			algorithmLabel = new JLabel();
			algorithmLabel.setText( "Algorithm:" );
		}
		return algorithmLabel;
	}

	/**
	 * @return
	 */
	private JComboBox getAlgorithmComboBox()
	{
		if( algorithmComboBox == null )
		{
			algorithmComboBox = new JComboBox( new Object[]{ "k-means" } );
		}
		return algorithmComboBox;
	}

	/**
	 * @return
	 */
	private JScrollPane getScrollPane()
	{
		if( scrollPane == null )
		{
			scrollPane = new JScrollPane();
			scrollPane.setViewportView( getTable() );
		}
		return scrollPane;
	}

	/**
	 * @return
	 */
	private JTable getTable()
	{
		if( table == null )
		{
			table = new JTable( tableModel );
		}
		return table;
	}

	/**
	 * @return
	 */
	private JPanel getButtonsPane()
	{
		if( buttonsPane == null )
		{
			buttonsPane = new JPanel();
			final FlowLayout flowLayout = new FlowLayout();
			flowLayout.setVgap( 0 );
			flowLayout.setHgap( 12 );
			buttonsPane.setLayout( flowLayout );
			buttonsPane.add( getOkButton() );
		}
		return buttonsPane;
	}

	/**
	 * @return
	 */
	private JButton getOkButton()
	{
		if( okButton == null )
		{
			okButton = new JButton();
			okButton.setText( "OK" );
			okButton.addActionListener( new ActionListener(){
				@Override
				public void actionPerformed( ActionEvent e )
				{
					ok();
				}
			} );
		}
		return okButton;
	}

	/**
	 * @return
	 */
	private JLabel getNodeLabel()
	{
		if( nodeLabel == null )
		{
			nodeLabel = new JLabel();
			nodeLabel.setText( "* Note: k<2 �?�Ը�����ݽ�����ɢ������" );
		}
		return nodeLabel;
	}
	/**
	 * @return
	 */
}
